﻿using Cyotek.Web.BbCodeFormatter;
using Microsoft.Practices.Unity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Tippelde.Services.Dtos;
using Tippelde.Services.Groups;
using Tippelde.Services.News;
using Tippelde.Web.Helpers;
using Tippelde.Web.Models.Group;
using Tippelde.Web.Models.News;

namespace Tippelde.Web.Controllers
{
    public class NewsController : Controller
    {
        [Dependency]
        public INewsManager NewsManager { get; set; }

        [Dependency]
        public IGroupManager GroupManager { get; set; }

        //
        // GET: /News/
        public ActionResult Index(int? page)
        {
            var model = new NewsListModel
            {
                News = NewsManager.GetNews(User.Identity.IsAuthenticated ? User.Identity.Name : null, page),
                HasAnyEditorRights = User.Identity.IsAuthenticated ? (User.IsInRole("newsmanager") || CacheManager.Current.UserHasAnyEditorRights()) : false,
                Groups = User.Identity.IsAuthenticated ? CacheManager.Current.GetGroupsForUser() : null
            };
            return View(model);
        }

        [Authorize]
        public ActionResult Group(int Id, int? page)
        {
            var model = new NewsListModel();
            try
            {
                model.HasAnyEditorRights = (User.IsInRole("newsmanager") || CacheManager.Current.UserHasAnyEditorRights(Id));
                model.Groups = CacheManager.Current.GetGroupsForUser();
                model.News = NewsManager.GetNewsForGroup(User.Identity.Name, Id, page);
                ViewBag.SelectedGroupId = Id;
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("", ex);
            }
            return View("Index", model);
        }

        public ActionResult Details(string seoUrl)
        {
            try
            {
                var model = NewsManager.GetNews(User.Identity.IsAuthenticated ? User.Identity.Name : null, seoUrl);
                return View(model);
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("", ex);
                return View(new NewsWithRightsData());
            }
        }

        [Authorize]
        public ActionResult Create(bool? partial)
        {
            ViewBag.Action = "Create";
            var model = new CreateNewsModel()
            {
                GroupList = CacheManager.Current.GetGroupsForEditor().Select(
                 g => new SelectableGroupHeaderData
                 {
                     Id = g.Id,
                     IsSelected = false,
                     Name = g.Name,
                     ShortName = g.ShortName
                 }
                ).ToList(), 
                AllowAnonym = User.IsInRole("newsmanager"),
                AllowGlobalAuthenticated = User.IsInRole("newsmanager")
            };
            if (partial ?? false)
                return PartialView("_EditorPartial", model);
            return View("Editor", model);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        [Authorize]
        public ActionResult Create(CreateNewsModel model)
        {

            ViewBag.Action = "Create";
            var editableGroupIds = CacheManager.Current.GetGroupIdsForEditor();
            foreach (var key in new List<int>(model.Groups.Keys))
            {
                if (!editableGroupIds.Contains(key))
                {
                    model.Groups.Remove(key);
                }
            }

            if ((!User.IsInRole("newsmanager") && model.Groups.Count(kv => kv.Value == true) < 1) || (User.IsInRole("newsmanager") && !model.AllowGlobalAuthenticated && !model.AllowAnonym && model.Groups.Count(kv => kv.Value == true) < 1))
            {
                ModelState.AddModelError("", "Nincs csoport kiválasztva");
                model.GroupList = CacheManager.Current.GetGroupsForEditor().Select(
                 g => new SelectableGroupHeaderData
                 {
                     Id = g.Id,
                     IsSelected = false,
                     Name = g.Name,
                     ShortName = g.ShortName,
                 }).ToList();
                return View("Editor", model);
            }

            if (!ModelState.IsValid)
            {
                model.GroupList = CacheManager.Current.GetGroupsForEditor().Select(
                 g => new SelectableGroupHeaderData
                 {
                     Id = g.Id,
                     IsSelected = false,
                     Name = g.Name,
                     ShortName = g.ShortName,
                 }).ToList();
                foreach (var item in model.Groups)
                {
                    if (!item.Value)
                        continue;
                    var group = model.GroupList.SingleOrDefault(g => g.Id == item.Key);
                    if (group != null)
                    {
                        group.IsSelected = true;
                    }
                }
                return View("Editor", model);
            }
            DateTime now = DateTime.Now;
            NewsHeaderData nhd = new NewsHeaderData()
            {
                Title = model.Title,
                Content = model.Content,
                AddedAt = now,
                SeoUrl = String.Format("{0:yyyy-MM-dd} {1}", now, model.Title).ToSeoFriendlyUrl(),
                AllowGlobalAuthenticated = model.AllowGlobalAuthenticated && User.IsInRole("newsmanager"),
                AllowAnonym = model.AllowAnonym && User.IsInRole("newsmanager"),
            };

            try
            {
                var groupIds = model.Groups.Where(i => i.Value).Select(i => i.Key).ToList();
                NewsManager.Create(User.Identity.Name, nhd, groupIds, BbCodeClearer.Format(nhd.Content));
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("", ex);
                model.GroupList = CacheManager.Current.GetGroupsForEditor().Select(
                 g => new SelectableGroupHeaderData
                 {
                     Id = g.Id,
                     IsSelected = false,
                     Name = g.Name,
                     ShortName = g.ShortName
                 }).ToList();
                foreach (var item in model.Groups)
                {
                    if (!item.Value)
                        continue;
                    var group = model.GroupList.SingleOrDefault(g => g.Id == item.Key);
                    if (group != null)
                    {
                        group.IsSelected = true;
                    }
                }
                return View("Editor", model);
            }

            return RedirectToAction("Index");
        }

        [Authorize]
        public ActionResult Edit(int Id, bool? partial)
        {
            ViewBag.Action = "Edit";
            if (!GroupManager.HasAnyEditorRightsForNews(User.Identity.Name, Id) && !User.IsInRole("newsmanager"))
            {
                return RedirectToAction("Index");
            }
            var news = NewsManager.GetNews(User.Identity.Name, Id);
            var containingGroups = GroupManager.GetActiveGroupIdsForNews(Id);
            var model = new CreateNewsModel()
            {
                GroupList = CacheManager.Current.GetGroupsForEditor().Select(
                 g => new SelectableGroupHeaderData
                 {
                     Id = g.Id,
                     IsSelected = containingGroups.Contains(g.Id),
                     Name = g.Name,
                     ShortName = g.ShortName,
                 }
                ).ToList(),
                Id = news.Id,
                Content = news.Content,
                Title = news.Title,
                AllowAnonym = news.AllowAnonym,
                AllowGlobalAuthenticated = news.AllowGlobalAuthenticated,
            };
            if (partial ?? false)
                return PartialView("_EditorPartial", model);
            return View("Editor", model);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        [Authorize]
        public ActionResult Edit(CreateNewsModel model)
        {
            ViewBag.Action = "Edit";
            if (!GroupManager.HasAnyEditorRightsForNews(User.Identity.Name, model.Id))
            {
                return RedirectToAction("Index");
            }
            var editableGroupIds = CacheManager.Current.GetGroupIdsForEditor();
            foreach (var key in new List<int>(model.Groups.Keys))
            {
                if (!editableGroupIds.Contains(key))
                {
                    model.Groups.Remove(key);
                }
            }
            if (!ModelState.IsValid)
            {
                model.GroupList = CacheManager.Current.GetGroupsForEditor().Select(
                 g => new SelectableGroupHeaderData
                 {
                     Id = g.Id,
                     IsSelected = false,
                     Name = g.Name,
                     ShortName = g.ShortName
                 }).ToList();
                foreach (var item in model.Groups)
                {
                    if (!item.Value)
                        continue;
                    var group = model.GroupList.SingleOrDefault(g => g.Id == item.Key);
                    if (group != null)
                    {
                        group.IsSelected = true;
                    }
                }
                return View("Editor", model);
            }
            if ((!User.IsInRole("newsmanager") && model.Groups.Count(kv => kv.Value == true) < 1) || (User.IsInRole("newsmanager") && !model.AllowGlobalAuthenticated && !model.AllowAnonym && model.Groups.Count(kv => kv.Value == true) < 1))
            {
                ModelState.AddModelError("", "Nincs csoport kiválasztva");
                model.GroupList = CacheManager.Current.GetGroupsForEditor().Select(
                 g => new SelectableGroupHeaderData
                 {
                     Id = g.Id,
                     IsSelected = false,
                     Name = g.Name,
                     ShortName = g.ShortName,
                 }).ToList();
                return View("Editor", model);
            }
            NewsHeaderData nhd = new NewsHeaderData()
            {
                Id = model.Id,
                Title = model.Title,
                Content = model.Content,
                AllowAnonym = model.AllowAnonym && User.IsInRole("newsmanager"),
                AllowGlobalAuthenticated = model.AllowGlobalAuthenticated && User.IsInRole("newsmanager")
            };
            try
            {
                var groupIds = model.Groups.Where(i => i.Value).Select(i => i.Key).ToList();
                NewsManager.Edit(User.Identity.Name, nhd, groupIds, BbCodeClearer.Format(nhd.Content));
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("", ex);
                model.GroupList = CacheManager.Current.GetGroupsForEditor().Select(
                 g => new SelectableGroupHeaderData
                 {
                     Id = g.Id,
                     IsSelected = false,
                     Name = g.Name,
                     ShortName = g.ShortName
                 }).ToList();
                foreach (var item in model.Groups)
                {
                    if (!item.Value)
                        continue;
                    var group = model.GroupList.SingleOrDefault(g => g.Id == item.Key);
                    if (group != null)
                    {
                        group.IsSelected = true;
                    }
                }
                return View("Editor", model);
            }
            return RedirectToAction("Index");
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Delete(int Id)
        {
            if (GroupManager.HasAnyEditorRightsForNews(User.Identity.Name, Id) || User.IsInRole("newsmanager"))
            {
                NewsManager.Delete(Id);
            }
            return RedirectToAction("Index");
        }

    }
}